home *** CD-ROM | disk | FTP | other *** search
/ Merciful 2 / Merciful - Disc 2.iso / software / d / dustv1.91.lha / Dust / Tutorial3 / Source / PExample.c next >
C/C++ Source or Header  |  1994-09-25  |  11KB  |  342 lines

  1. /*
  2. ###############################################################################
  3. #                                                                             #
  4. #                 Dust V1.04 - Copyright ©1994 by A.Maschke                   #
  5. #                           All rights reserved.                              #
  6. #-----------------------------------------------------------------------------#
  7. #                                                                             #
  8. #              Tutorial 3: Create a particle-explosion using Dust             #
  9. #                            -changes only particle-positions                 #
  10. #                            -writes scriptfile to stdout                     #
  11. #                                                                             #
  12. # OPERATION: 1. write a script which creates a particle-object and outputs    #
  13. #               the PPOS-array and OCOUNT, e.g.:                              #
  14. #                "load(1,objects/s1)                                          #
  15. #                 load(2,objects/c1)                                          #
  16. #                 o2p(1,2,1,p)                                                #
  17. #                 savep(1,PExample.obj)                                       #
  18. #                 getocount(1)                                                #
  19. #                 !copy T:Dust.output PExample.oCount                         #
  20. #                 getppos(1)                                                  #
  21. #                 !copy T:Dust.output PExample.PPOS                           #
  22. #                 !delete T:Dust.output                                       #
  23. #                 exit"                                                       #
  24. #             2. execute this script using Dust                               #
  25. #             3. execute this programm writing "PExample >pex.bat"            #
  26. #             4. execute the created file "pex.bat" using Dust"               #
  27. #             5. That's it (You got 12 particle objects).                     #
  28. #                                                                             #
  29. #-----------------------------------------------------------------------------#
  30. #                                                                             #
  31. #      Language: ANSI-C                                                       #
  32. #      Compiler: MCPP                                                         #
  33. # Last modified: 25 September 1994                                            #
  34. #                                                                             #
  35. #      Problems: GNU-C                                                        #
  36. #                Other float-format ? Please help !                           #
  37. #                                                                             #
  38. ###############################################################################
  39. */
  40. /*
  41. *******************************************************************************
  42. * NOTE: This code is Public Domain. You can do what you want with it.         *
  43. *******************************************************************************
  44. */
  45. #include <stdio.h>
  46. #include <math.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49.  
  50. const ZERO=0.0001;
  51. struct Vector{float x;float y;float z;};
  52.  
  53. int oCount;  /* number of particles (to be read) */
  54. struct Vector* pos; /* particle positions (to be read) */
  55. float bb;           /* needed by RND2() */
  56. int i,j; 
  57. float centreX,centreY,centreZ; /* centre of all particles */
  58.  
  59. /*
  60. *******************************************************************************
  61. * returns a factor between 0.9 and 1.0                                        *
  62. *******************************************************************************
  63. */
  64. float RND2()
  65. {
  66.  bb=(float) rand();
  67.  bb=bb/(float) RAND_MAX*900.0;
  68.  bb=bb+100.0;
  69.  bb=bb/10000.0;
  70.  if (rand()>16384) {return 1.0+bb;} else {return 1.0-bb;}
  71. }
  72. /*
  73. *******************************************************************************
  74. * generates a filename like "obj.0235"                                        * 
  75. *******************************************************************************
  76. */
  77. void GenFn(char* str1,int tt)
  78. {
  79.  printf("%s.",str1);
  80.  if (tt<1000) printf("0");
  81.  if (tt<100) printf("0");
  82.  if (tt<10) printf("0");
  83.  printf("%d",tt);
  84. }
  85. /*
  86. *******************************************************************************
  87. * Read (x,y,z)-array from EXFILE; this example: pos                           *
  88. *******************************************************************************
  89. */
  90. int ReadReal(char* fn,void* addr,int count)
  91. {
  92.  FILE* fh;
  93.  long len;
  94.  fh=fopen(fn,"r");
  95.  if (fh==NULL) return 1;
  96.  len=fread(addr,sizeof(struct Vector),count,fh);
  97.  fclose(fh);
  98.  if (len!=count) return 1;
  99.  return 0;
  100. }
  101. /*
  102. *******************************************************************************
  103. * Read a integer from EXFILE; this example: oCount                            *
  104. *******************************************************************************
  105. */
  106. int ReadInt(char* fn,void* addr)
  107. {
  108.  FILE* fh;
  109.  long len;
  110.  fh=fopen(fn,"rb");
  111.  if (fh==NULL) return 1;
  112.  len=fread(addr,2,1,fh);
  113.  fclose(fh);
  114.  if (len!=1) {return 1;} else {return 0;}
  115. }
  116. /*
  117. *******************************************************************************
  118. * Call the SETPxxx-Procedure of Dust to change the vector vp^[ind];           *
  119. * this example: SETPPOS(1,ind,pos^[ind].x,pos^[ind].x,pos^[ind].z)            *
  120. *******************************************************************************
  121. */
  122. void WritePXXX(float x,float y,float z,int ind,char* cmd)
  123. {
  124.  printf("\nSETP%s(1,%d,%f,%f,%f)",cmd,ind,x,y,z);
  125. }
  126. /*
  127. *******************************************************************************
  128. * Main procedure                                                              *
  129. *  Arguments:                                                                 *
  130. *    frames: number of objects (frames)                                       *
  131. *        fn: base filename of the objects                                     *
  132. *     timep: time to process                                                  *
  133. *        gp: gravity constant, e.g. -10.0 (negative)                          *
  134. *      etap: friction (Stokes), e.g. -0.00001 (negative)                      *
  135. *      vv0p: speed at t=0 (positive)                                          *
  136. *       fmt: save-format-string, e.g. "TDDD"                                  *
  137. *                                                                             *
  138. *******************************************************************************
  139. */
  140. /*
  141. *******************************************************************************
  142. * calculates centre of all poarticles                                         *
  143. *******************************************************************************
  144. */
  145. void getCentre(float ggg)
  146. {
  147.  float xmin,xmax,ymin,ymax,zmin,zmax;
  148.  xmin=pos[0].x;xmax=xmin;ymin=pos[0].y;ymax=ymin;zmin=pos[0].z;zmax=zmin;
  149.  for(i=1;i<oCount;i++) {
  150.   if (xmin>pos[i].x) xmin=pos[i].x;
  151.   if (xmax<pos[i].x) xmax=pos[i].x;
  152.   if (ymin>pos[i].y) ymin=pos[i].y;
  153.   if (ymax<pos[i].y) ymax=pos[i].y;
  154.   if (zmin>pos[i].z) zmin=pos[i].z;
  155.   if (zmax<pos[i].z) zmax=pos[i].z;
  156.  }
  157.  centreX=xmin+(xmax-xmin)/2.0;
  158.  centreY=ymin+(ymax-ymin)/2.0;
  159.  centreZ=zmin+(zmax-zmin)/2.0;
  160.  /* move the object into the positive z-space if necessary */
  161.  if ((zmin<0) && (ggg!=0.0)) {
  162.   xmin=1.1*zmin;
  163.   for(i=0;i<oCount;i++) {
  164.    pos[i].z=pos[i].z-xmin;
  165.   }
  166.   zmin=zmin-xmin;
  167.   zmax=zmax-xmin;
  168.   /* update centreZ */
  169.   centreZ=zmin+(zmax-zmin)/2.0;
  170.   /* change the original object */
  171.   printf("\n;move the object into the positive z-space");
  172.   for(i=0;i<oCount;i++) {
  173.    WritePXXX(pos[i].x,pos[i].y,pos[i].z,i,"POS");
  174.   }
  175.  }
  176. }
  177.  
  178. void DoIt(int frames,char* fn,float timep,float gp,float etap,float vv0p,char* fmt)
  179. {
  180.  struct Vector *v0;
  181.  float *oldX,*oldY;
  182.  float eta,g,vv0,time,timestep,t,A,Ae,Aet,V0,X0,hh;
  183.  float dx,dy,dz,vb,cx,cy,cz,newX,newY,newZ;
  184.  float e1,e2,e3,e4,e5,e6;
  185.  if (frames<1) return;
  186.  /* allocate some arrays */
  187.  v0=(struct Vector*)calloc(oCount,sizeof(struct Vector));
  188.  if (v0==NULL) return;
  189.  oldX=(float*)calloc(oCount,sizeof(float));
  190.  if (oldX==NULL) {free(v0);return;}
  191.  oldY=(float*)calloc(oCount,sizeof(float));
  192.  if (oldY==NULL) {free(oldX);free(v0);return;}
  193.  time=timep;
  194.  g=gp;
  195.  eta=etap;
  196.  vv0=vv0p;
  197.  if (g>0.0) {printf("\ng-error.\n");g=-10.0;}
  198.  if (vv0<ZERO) {printf("\nvv0-error.\n");vv0=1.0;}
  199.  if (eta>=0.0) {printf("\neta-error.\n");eta=-0.00001;}
  200.  getCentre(g);
  201.  
  202.  /* compute speed at t=0 (vectors) */
  203.  for(i=0;i<oCount;i++) {
  204.   dx=pos[i].x-centreX;
  205.   dy=pos[i].y-centreY;
  206.   dz=pos[i].z-centreZ;
  207.   vb=dx*dx;
  208.   vb=vb+dy*dy;
  209.   vb=vb+dz*dz;
  210.   vb=sqrt(vb);
  211.   e1=RND2();
  212.   e2=RND2();
  213.   e3=RND2();
  214.   v0[i].x=dx/vb*vv0*e1;
  215.   v0[i].y=dy/vb*vv0*e2;
  216.   v0[i].z=dz/vb*vv0*e3;
  217.  }
  218.  
  219.  /* generate filename and say "save it" (first and unchanged object) */
  220.  if (!strcmp(fmt,"TDDD")) {printf("\nSavePTDDD(1,");}
  221.  else {
  222.   if (!strcmp(fmt,"VS")) {printf("\nSavePVS(1,");} else {printf("\nSaveP(1,");}
  223.  }
  224.  GenFn(fn,1);
  225.  printf(")");
  226.  
  227.  /* main loop */
  228.  timestep=time/(frames-1);
  229.  for(i=1;i<frames;i++) {
  230.  
  231.   /* output frame as comment */
  232.   printf("\n;frame %d",i);
  233.  
  234.   t=i*timestep; /* actual time */
  235.  
  236.   for(j=0;j<oCount;j++) {
  237.  
  238.    /* particle-size (friction) (to calculate this the array PSCL is needed) */
  239.    e1=RND2();
  240.    A=e1*10.0;
  241.    Ae=A*eta;
  242.    Aet=Ae*t;
  243.    hh=exp(Aet);
  244.  
  245.    /* compute x-coordinate */
  246.    V0=v0[j].x;
  247.    X0=pos[j].x;
  248.    cx=X0*Ae-V0;
  249.    cx=cx+V0*hh;
  250.    cx=cx/Ae;
  251.  
  252.    /* compute y-coordinate */
  253.    V0=v0[j].y;
  254.    X0=pos[j].y;
  255.    cy=X0*Ae-V0;
  256.    cy=cy+V0*hh;
  257.    cy=cy/Ae;
  258.  
  259.    /* compute z-coordinate */
  260.    V0=v0[j].z;
  261.    X0=pos[j].z;
  262.    cz=X0*Ae*Ae-g;
  263.    cz=cz-V0*Ae;
  264.    cz=cz+g*hh;
  265.    cz=cz+V0*Ae*hh;  
  266.    cz=cz-g*Aet;
  267.    cz=cz/(Ae*Ae);
  268.    /* motion must stop at z=0 */
  269.    if (cz>0.0) {
  270.     oldX[j]=cx;
  271.     oldY[j]=cy;
  272.    }
  273.    else {
  274.     cz=0.0;
  275.     if (i>1) {
  276.      cx=oldX[j];
  277.      cy=oldY[j];
  278.     }
  279.     else {
  280.      oldX[j]=cx;
  281.      oldY[j]=cy;
  282.     }
  283.    }
  284.  
  285.    /* the final posion */
  286.    newX=cx;
  287.    newY=cy;
  288.    newZ=cz;
  289.  
  290.    /* say: "apply them" */
  291.    WritePXXX(newX,newY,newZ,j,"POS");
  292.  
  293.   }
  294.   
  295.   /* generate filename and say "save it" */
  296.   if (!strcmp(fmt,"TDDD")) {printf("\nSavePTDDD(1,");}
  297.   else {
  298.    if (!strcmp(fmt,"VS")) {printf("\nSavePVS(1,");} else {printf("\nSaveP(1,");}
  299.   }
  300.   GenFn(fn,i+1);
  301.   printf(")");
  302.  
  303.  }
  304.  
  305.  /* clean up */
  306.  free(oldY);free(oldX);free(v0);
  307. }
  308.  
  309. void main()
  310. {
  311.  /* load the ppos-array */
  312.  if (ReadInt("shit:tmp/PEXAMPLE.OCOUNT",&oCount)==0) {
  313.   oCount=oCount/65536;
  314.   pos=(struct Vector*)calloc(oCount,sizeof(struct Vector));
  315.   if (pos==NULL) {
  316.    printf("\nCouldn't allocate PPOS-array.\n");
  317.   }
  318.   else
  319.   { 
  320.    if (ReadReal("shit:tmp/PEXAMPLE.PPOS",&pos[0],oCount)==0) {
  321.     /* tell Dust to load the Source-Particle-Object */
  322.     printf("\nloadp(1,PExample.obj)");
  323.     /* do it !*/
  324.     DoIt(12,"obj",12.8,-10.0,-0.001,52,"TDDD");
  325.     /* important*/
  326.     printf("\n");
  327.     free(pos);
  328.    }
  329.    else
  330.    {
  331.     free(pos);
  332.     printf("\nCouldn't read PPOS-file.\n");
  333.    }
  334.   }
  335.  }
  336.  else
  337.  {
  338.   printf("\nCouldn't read OCOUNT-file.\n");
  339.  }
  340. }
  341.  
  342.